package cn.flying.cloud.esb.core.convert;

import java.util.List;
import java.util.Optional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;

import cn.flying.cloud.esb.core.model.FieldMapping;

/**
 * Json字段映射转换
 *
 * @author: admin
 * @date: 2025年01月09日 14:51
 * @version: 1.0
 */
public class JsonMapper {

    private static final Logger logger = LoggerFactory.getLogger(JsonMapper.class);
    private final ObjectMapper objectMapper = new ObjectMapper();
    private final Cache<String, List<FieldMapping>> mappingCache;
    private final List<FieldMapping> mappings;

    public JsonMapper(List<FieldMapping> mappings) {
        this.mappings = mappings;
        this.mappingCache = Caffeine.newBuilder().build();
    }

    /**
     * 将源JSON字符串转换为目标系统的JSON字符串。
     */
    public String transform(String sourceJson) throws Exception {
        JsonNode sourceTree = objectMapper.readTree(sourceJson);
        ObjectNode targetTree = objectMapper.createObjectNode();

        for (FieldMapping mapping : mappings) {
            try {
                Optional<JsonNode> valueOpt = getValueByPath(sourceTree, mapping.getSourcePath());
                valueOpt.ifPresent(jsonNode -> setValueByPath(targetTree, mapping.getTargetPath(), jsonNode, mapping.getType()));
            } catch (Exception e) {
                logger.error("Error processing mapping: " + mapping, e);
                throw new MappingException("Failed to apply mapping: " + mapping, e);
            }
        }

        return objectMapper.writeValueAsString(targetTree);
    }

    /**
     * 从嵌套的JSON节点中获取值。
     */
    private Optional<JsonNode> getValueByPath(JsonNode jsonNode, String path) {
        String[] parts = path.split("\\.");
        JsonNode currentNode = jsonNode;
        for (String part : parts) {
            if (currentNode == null || !currentNode.has(part)) {
                return Optional.empty();
            }
            currentNode = currentNode.get(part);
        }
        return Optional.ofNullable(currentNode);
    }

    /**
     * 在嵌套的JSON节点中设置值。
     */
    private void setValueByPath(ObjectNode objectNode, String path, JsonNode value, Class<?> targetType) {
        String[] parts = path.split("\\.");
        ObjectNode currentNode = objectNode;
        for (int i = 0; i < parts.length - 1; i++) {
            String part = parts[i];
            if (!currentNode.has(part)) {
                ObjectNode newNode = currentNode.objectNode();
                currentNode.set(part, newNode);
                currentNode = newNode;
            } else {
                currentNode = (ObjectNode) currentNode.get(part);
            }
        }
        String finalPart = parts[parts.length - 1];

        if (targetType == Integer.class) {
            currentNode.put(finalPart, value.asInt());
        } else if (targetType == String.class) {
            currentNode.putPOJO(finalPart, value);
        } else {
            currentNode.set(finalPart, value);
        }

//        if (parts.length == 1) {
//            if (targetType != null && !targetType.isInstance(value)) {
//                value = convertType(value, targetType);
//            }
//            objectNode.set(parts[0], value.deepCopy());
//        } else {
//            ObjectNode childNode = objectNode.with(parts[0]);
//            setValueByPath(childNode, parts[1], value, targetType);
//        }
    }

    /**
     * 对值进行类型转换。
     */
    private JsonNode convertType(JsonNode value, Class<?> targetType) {
        try {
            if (Integer.class.equals(targetType)) {
                return objectMapper.valueToTree(Integer.parseInt(value.asText()));
            } else if (Double.class.equals(targetType)) {
                return objectMapper.valueToTree(Double.parseDouble(value.asText()));
            } else if (Boolean.class.equals(targetType)) {
                return objectMapper.valueToTree(Boolean.parseBoolean(value.asText()));
            }
            // 添加更多类型转换规则...
        } catch (NumberFormatException e) {
            logger.warn("Failed to convert value to type: " + targetType.getName(), e);
        }
        return value;
    }

    /**
     * 处理数组或列表类型。
     */
    private void handleArray(ObjectNode target, String path, ArrayNode array, Class<?> elementType) {
        ArrayNode targetArray = target.putArray(path);
        for (JsonNode item : array) {
            targetArray.add(convertType(item, elementType));
        }
    }

    // 自定义异常类
    public static class MappingException extends RuntimeException {
        public MappingException(String message, Throwable cause) {
            super(message, cause);
        }
    }

    // 测试方法
    public static void main(String[] args) throws Exception {
//        // 假设这是你要转换的 JSON 字符串
//        String jsonString = "{\"name\":\"John\", \"age\":30, \"city\":\"New York\"}";
//
//        // 创建 ObjectMapper 实例用于解析 JSON
//        ObjectMapper jsonMapper = new ObjectMapper();
//
//        // 将 JSON 字符串反序列化为 Map 对象
////        Map<String, Object> map = jsonMapper.readValue(jsonString, Map.class);
//        JsonNode jsonNode = jsonMapper.readTree(jsonString);
//
//        // 创建 XmlMapper 实例用于生成 XML
//        XmlMapper xmlMapper = new XmlMapper();
//
//        // 将 Map 对象序列化为 XML 字符串
//        String xmlString = xmlMapper.writeValueAsString(jsonNode);
//
//        // 输出 XML 字符串
//        System.out.println(xmlString);


//        ObjectMapper mapper = new ObjectMapper();
//        List<FieldMapping> mappings = Lists.newArrayList(
//                new FieldMapping("person.name", "user.fullName"),
//                new FieldMapping("person.age", "user.age", Integer.class),
//                new FieldMapping("person.hobbies", "user.hobbies", String.class),
//                new FieldMapping("person.ddd.name", "user.ddd.name")
//                // 添加更多映射规则
//        );
//        System.out.println(mapper.writeValueAsString(mappings));
//
//        // 示例输入JSON
//        String json = "{\"person\":{\"fullName\":\"John Doe\",\"age\":30,\"hobbies\":[\"reading\",\"swimming\"],\"ddd\":{\"name\":\"张三\"}}}";
//        Map<String, Object> map = mapper.readValue(json, new TypeReference<Map<String, Object>>() {
//        });
//
//
//        System.out.println(map);

//        try {
//            // 示例映射规则
//            List<FieldMapping> mappings = Lists.newArrayList(
//                new FieldMapping("person.name", "user.fullName"),
//                new FieldMapping("person.age", "user.age", Integer.class),
//                new FieldMapping("person.hobbies", "user.hobbies", String.class),
//                new FieldMapping("person.ddd.name", "user.ddd.name")
//                // 添加更多映射规则
//            );
//
//            // 创建映射器实例
//            JsonMapper mapper = new JsonMapper(mappings);
//
//            // 示例输入JSON
//            String inputJson = "{\"person\":{\"fullName\":\"John Doe\",\"age\":30,\"hobbies\":[\"reading\",\"swimming\"],\"ddd\":{\"name\":\"张三\"}}}";
//
//            // 执行转换并打印结果
//            System.out.println(mapper.transform(inputJson));
//        } catch (Exception e) {
//            logger.error("Transformation failed", e);
//        }
    }
}